package cn.ytxy.double_system_data_visualization_demo.user.service.Impl;


import cn.ytxy.double_system_data_visualization_demo.base.exception.ParamsException;
import cn.ytxy.double_system_data_visualization_demo.base.exception.ServiceException;
import cn.ytxy.double_system_data_visualization_demo.base.response.StatusCode;
import cn.ytxy.double_system_data_visualization_demo.user.mapper.DepartmentMapper;
import cn.ytxy.double_system_data_visualization_demo.user.mapper.ScoreChangeMapper;
import cn.ytxy.double_system_data_visualization_demo.user.mapper.UserMapper;
import cn.ytxy.double_system_data_visualization_demo.user.pojo.dto.ScoreChangeParam;
import cn.ytxy.double_system_data_visualization_demo.user.pojo.dto.UserQuery;
import cn.ytxy.double_system_data_visualization_demo.user.pojo.entity.User;
import cn.ytxy.double_system_data_visualization_demo.user.pojo.vo.DepartmentGUANJUNVO;
import cn.ytxy.double_system_data_visualization_demo.user.pojo.vo.DepartmentInfoVO;
import cn.ytxy.double_system_data_visualization_demo.user.pojo.vo.DepartmentVO;
import cn.ytxy.double_system_data_visualization_demo.user.pojo.vo.UserVO;
import cn.ytxy.double_system_data_visualization_demo.user.service.DepartmentService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.beans.Transient;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * @ClassName DepartmentServiceImpl ZGJ周冠军 YGJ月冠军
 * @Description TODO
 * @Author renhong~Deng
 * @Date 2025/4/30 15:30
 * @Version 1.0
 */
@Slf4j
@Service
public class DepartmentServiceImpl implements DepartmentService {
    @Autowired
    private DepartmentMapper departmentMapper;
    @Autowired
    private UserMapper userMapper;
    @Autowired
    ScoreChangeMapper scoreChangeMapper;

    /**
     * 查询部门信息
     *
     * @param departmentName
     * @return
     */

    @Override
    @Transient
    public List<DepartmentVO> selectDepartment(String departmentName) {
//    if (log.isDebugEnabled()) {
//        log.debug("查询部门业务：departmentName={}", departmentName);
//    }
        log.info("查询部门: {}", departmentName);
        // 如果departmentName为空则返回全部信息
        if (departmentName == null) {
            List<String> allDepartmentNames = departmentMapper.selectAllDepartmentNames();
            List<DepartmentVO> allDepartments = new ArrayList<>();

            for (String name : allDepartmentNames) {
                List<DepartmentVO> departmentVOS = selectDepartment(name);// 循环调用当前方法
                allDepartments.addAll(departmentVOS);
            }

            return allDepartments;
        }

        DepartmentInfoVO departmentInfoVO = departmentMapper.selectDepartment(departmentName);
        DepartmentGUANJUNVO departmentGUANJUNVO = departmentMapper.selectDepartmentGUANJUN();

        DepartmentVO departmentVO = new DepartmentVO();
        departmentVO.setDepartmentName(departmentName);

        if (departmentInfoVO != null) {
            departmentVO.setDepartmentScoreTotal(departmentInfoVO.getDepartmentScoreTotal());
            departmentVO.setDepartmentUserCount(departmentInfoVO.getDepartmentUserCount());
        }

        if (departmentGUANJUNVO != null) {
            departmentVO.setDepartmentZGJCount(departmentGUANJUNVO.getDepartmentZGJCount());
            departmentVO.setDepartmentYGJCount(departmentGUANJUNVO.getDepartmentYGJCount());
        }

        List<DepartmentVO> result = new ArrayList<>();
        result.add(departmentVO);
        return result;
    }


    /**
     * 新增部门
     *
     * @param departmentName 新增部门名称
     */
    @Override
    public void addDepartment(String departmentName) {
        departmentMapper.addDepartment(departmentName);
    }

    /**
     * 修改部门名称
     * <p>
     * 本方法用于更新系统中的部门名称，包括在部门表和用户表中更新旧的部门名称为新的部门名称
     * 这是因为部门名称的更改需要在系统中的所有相关地方进行同步更新，以保持数据的一致性
     *
     * @param oldDepartmentName 旧的部门名称，用于定位需要修改的部门
     * @param newDepartmentName 新的部门名称，用于替换旧的部门名称
     */
    @Transient
    @Override
    public void editDepartment(String oldDepartmentName, String newDepartmentName) {
        // 记录修改部门名称业务的日志，包含旧的部门名称和新的部门名称
        log.debug("修改部门名称业务：oldDepartmentName={},newDepartmentName={}", oldDepartmentName, newDepartmentName);

        // 在部门表中更新部门名称
        departmentMapper.editDepartment(oldDepartmentName, newDepartmentName);

        // 在用户表中更新相关的部门名称，以保持数据一致性
        userMapper.updateUserDepartmentName(oldDepartmentName, newDepartmentName);
    }


    /**
     * 删除指定部门及其所有相关用户
     * <p>
     * 此方法首先删除指定名称的部门，然后查询所有属于该部门的用户，并逐个删除这些用户
     *
     * @param departmentName 部门名称，用于标识并删除部门
     */
    @Override
    public void deleteDepartment(String departmentName) {
        // 删除指定的部门
        departmentMapper.deleteDepartment(departmentName);

        // 创建用户查询对象，设置部门名称以查询该部门下的所有用户
        UserQuery userQuery = new UserQuery();
        userQuery.setDepartmentName(departmentName);

        // 查询属于指定部门的所有用户
        List<UserVO> userVOS = userMapper.selectUser(userQuery);

        // 遍历并删除属于该部门的所有用户
        userVOS.forEach(userVO -> userMapper.deleteUser(userVO.getId()));
    }


    /**
     * 为指定部门的所有用户添加部门分数
     *
     * @param departmentName  部门名称，用于查询该部门的所有用户
     * @param departmentScore 部门得分，将被添加到每个用户的成绩中
     * @param reason          加分的原因，用于记录分数变化的详细信息
     */
    @Override
    @Transient
    public void addDepartmentScore(String departmentName, Integer departmentScore, String reason) {
        // 校验部门名称是否为空
        if (departmentName == null || departmentName.trim().isEmpty()) {
            throw new ParamsException(StatusCode.VALIDATE_ERROR);
        }

        // 校验部门得分是否为正整数
        if (departmentScore <= 0) {
            throw new ParamsException(StatusCode.VALIDATE_ERROR);
        }

        // 校验原因是否为空
        if (reason == null || reason.trim().isEmpty()) {
            throw new ParamsException(StatusCode.VALIDATE_ERROR);
        }

        // 记录团队加分业务的日志信息
        log.debug("团队加分业务：departmentName={}, score={}, reason={}", departmentName, departmentScore, reason);

        // 创建用户查询对象，设置查询条件为指定的部门名称
        UserQuery userQuery = new UserQuery();
        userQuery.setDepartmentName(departmentName);

        // 查询指定部门的所有用户
        List<UserVO> userVOS = userMapper.selectUser(userQuery);

        // 遍历每个用户，为他们添加部门分数
        for (UserVO userVO : userVOS) {
            // 校验用户ID是否存在
            if (userVO.getId() == null) {
                throw new ServiceException(StatusCode.NOT_LOGIN);
            }

            // 根据用户ID查询用户详细信息
            User user = userMapper.selectById(userVO.getId());
            // 如果用户不存在，抛出未登录的异常
            if (user == null) {
                throw new ServiceException(StatusCode.NOT_LOGIN);
            }

            // 更新用户总分数
            user.setTotal(user.getTotal() + departmentScore);
            // 更新用户信息到数据库
            userMapper.updateUser(user);

            // 创建分数变化参数对象，用于记录分数变化的详细信息
            ScoreChangeParam scoreChangeParam = new ScoreChangeParam();
            scoreChangeParam.setUserId(userVO.getId());
            scoreChangeParam.setReason(reason);
            scoreChangeParam.setPoints(departmentScore);
            scoreChangeParam.setDate(new Date());

            // 记录分数变化信息到数据库
            scoreChangeMapper.addScore(scoreChangeParam);
        }
    }

    /**
     * 查询所有部门名称列表。
     * 
     * @return 返回包含所有部门名称的字符串列表。
     */
    public List<String> selectDepartmentName() {
        return departmentMapper.selectAllDepartmentNames();
    }

    @Override
    @Transient
    public void subtractDepartmentScore(String departmentName, Integer departmentScore, String reason) {
        // 校验部门名称是否为空
        if (departmentName == null || departmentName.trim().isEmpty()) {
            throw new ParamsException(StatusCode.VALIDATE_ERROR);
        }

        // 校验部门得分是否为正整数（减分值应为正数）
        if (departmentScore <= 0) {
            throw new ParamsException(StatusCode.VALIDATE_ERROR);
        }

        // 校验原因是否为空
        if (reason == null || reason.trim().isEmpty()) {
            throw new ParamsException(StatusCode.VALIDATE_ERROR);
        }

        // 记录团队减分业务的日志信息
        log.debug("团队减分业务：departmentName={}, score={}, reason={}", departmentName, departmentScore, reason);

        // 创建用户查询对象，设置查询条件为指定的部门名称
        UserQuery userQuery = new UserQuery();
        userQuery.setDepartmentName(departmentName);

        // 查询指定部门的所有用户
        List<UserVO> userVOS = userMapper.selectUser(userQuery);

        // 遍历每个用户，为他们减去部门分数
        for (UserVO userVO : userVOS) {
            // 校验用户ID是否存在
            if (userVO.getId() == null) {
                throw new ServiceException(StatusCode.NOT_LOGIN);
            }

            // 根据用户ID查询用户详细信息
            User user = userMapper.selectById(userVO.getId());
            // 如果用户不存在，抛出未登录的异常
            if (user == null) {
                throw new ServiceException(StatusCode.NOT_LOGIN);
            }

            // 更新用户总分数（减分）
            user.setTotal(user.getTotal() - departmentScore);
            // 更新用户信息到数据库
            userMapper.updateUser(user);

            // 创建分数变化参数对象，用于记录分数变化的详细信息
            ScoreChangeParam scoreChangeParam = new ScoreChangeParam();
            scoreChangeParam.setUserId(userVO.getId());
            scoreChangeParam.setReason(reason);
            scoreChangeParam.setPoints(-departmentScore); // 减分记录为负数
            scoreChangeParam.setDate(new Date());

            // 记录分数变化信息到数据库
            scoreChangeMapper.addScore(scoreChangeParam);
        }
    }
}
